#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct nlist
{    
    char *name;
    char *defn;  
    struct nlist *next;  
} Nlist;

#define HASHSIZE 101
static Nlist *hashtab[HASHSIZE];

void printNlist(void)
{
    int i;
    for(i = 0; i < HASHSIZE; i++){
        if(hashtab[i] != NULL){
            printf("index:%d, name:%s, defn:%s\n", i, hashtab[i]->name, hashtab[i]->defn);
        }
    }
}

unsigned hash(char *s)
{
    unsigned hashval;
    for(hashval = 0; *s != '\0'; s++){
        hashval = *s + 31 * hashval;
    }
    return hashval % HASHSIZE;
}

Nlist *lookup(char *s)
{
    Nlist *np;
    for(np = hashtab[hash(s)]; np != NULL; np = np->next){
        if(0 == strcmp(s, np->name)){
            return np;
        }
    }
    return NULL;
}

Nlist *install(char *name, char *defn)
{
    Nlist *np;
    unsigned hashval;

    np = lookup(name);    
    if(np == NULL){
        np = (Nlist *)malloc(sizeof(*np));
        np->name = strdup(name);
        if(np == NULL || np->name == NULL){
            return NULL;
        }
        hashval = hash(name);
        np->next = hashtab[hashval];
        hashtab[hashval] = np;
    }else{
        free((void *)np->defn);
    }    
    np->defn = strdup(defn);
    if(np->defn == NULL){
        return NULL;
    }

    return np;
}

void undef(char *name)
{
    Nlist *np, *tp;
    unsigned hashval = hash(name);
    for(np = hashtab[hashval]; np != NULL; np = np->next){
        if(0 == strcmp(name, np->name)){
            hashtab[hashval] = NULL;
            while (np->next)
            {
                /* code */
                free((void *)np->name);
                free((void *)np->defn);                
                tp = np;
                free((void *)np);
                np = tp->next;
            }        
        }
    }
}

int main(void)
{
    Nlist *np;
    np = install("age", "15");
    printf("%p,%p,%p, %p\n", np, np->name,np->defn, np->next);
    np = install("name", "yangke");
    printf("%p,%p,%p, %p\n", np, np->name,np->defn, np->next);
    np = install("sex", "male");
    printf("%p,%p,%p, %p\n", np, np->name,np->defn, np->next);
    np = install("address", "HF");
    printf("%p,%p,%p, %p\n", np, np->name,np->defn, np->next);
    np = install("ID", "150221");
    printf("%p,%p,%p, %p\n", np, np->name,np->defn, np->next);
    np = install("age","33");
    printf("%p,%p,%p, %p\n", np, np->name,np->defn, np->next);

    printNlist();
    printf("------------\n");
    undef("age");
    printNlist();

    return 0;
}